#include <QtSql>
#include <QMessageBox>
#include <QFileDialog>
#include "headers/inventoryreport.h"
#include "headers/selectworkplace.h"
#include "headers/selectdepartment.h"
#include "headers/createinventoryreport.h"
#include "headers/sqltreemodel.h"
#include "headers/workplacemodel.h"
#include "headers/devicemodel.h"
#include "headers/devicemodelcontrol.h"

InventoryReport::InventoryReport(QWidget *parent) :
    QWidget(parent){
    setupUi(this);
    departmentId = 0;
    workPlaceId = 0;
    populateCBox("id","departments","firm = 1","<Выберите фирму>",firm);
    cInvRep = new CreateInventoryReport(this);
    orgTexModel = new DeviceModelControl(this,"");
    modelDepart = new SqlTreeModel(this);
    modelDepart->setHeaderData(0,Qt::Horizontal,tr("Подразделения"));
    wpModel = new WorkPlaceModel(this);
}
void InventoryReport::on_firm_currentIndexChanged(int index)
{
    if(index > 0)
        createButton->setEnabled(true);
    else
        createButton->setEnabled(false);
}

void InventoryReport::on_selectDepButton_clicked()
{
    SelectDepartment *sd = new SelectDepartment(this);
    connect(sd,SIGNAL(addDepartment(int,QString,int)),this,SLOT(setDepartment(int,QString)));
    sd->exec();
}
void InventoryReport::on_selectWPButton_clicked()
{
    SelectWorkPlace *swp = new SelectWorkPlace(this,0,true);
    connect(swp,SIGNAL(addWorkPlace(int,QString,int)),this,SLOT(setWorkPlase(int,QString)));
    swp->exec();
}
void InventoryReport::setWorkPlase(int wpId, const QString &wpNm)
{
    workPlaceId = wpId;
    wpName->setText(wpNm);
    createButton->setEnabled(true);
}

void InventoryReport::setDepartment(int depId, const QString &depNm)
{
    departmentId = depId;
    depName->setText(depNm);
    createButton->setEnabled(true);
}

void InventoryReport::populateCBox(const QString &idName, const QString &tableName,
                            const QString &filter, const QString &nullStr, QComboBox *cBox)
{
    cBox->clear();
    cBox->addItem(nullStr);
    QSqlQuery query;
    if(filter.isNull() || filter.isEmpty())
        query.exec(QString("SELECT %2,name FROM %1;").arg(tableName).arg(idName));
    else
        query.exec(QString("SELECT %2,name FROM %1 WHERE %3;").arg(tableName).arg(idName).arg(filter));
    if (query.lastError().type() != QSqlError::NoError)
    {
        QMessageBox::information(this, tr("Ошибка"),
                                 tr("Не удалось заполнить комбобокс %2:\n %1")
                                 .arg(query.lastError().text())
                                 .arg(cBox->objectName()),
                                 tr("Закрыть"));
        return;
    }
    cBox->setMaxCount(query.size()+1);
    while(query.next())
        cBox->addItem(query.value(1).toString(),query.value(0).toInt());
}
void InventoryReport::populateModDep(int organizationId)
{
    modelDepart->setTable("departments");
    modelDepart->setFilter(QString("id IN (SELECT c.id FROM "
                                   "(SELECT * FROM departments) n, "
                                   "(SELECT * FROM tree) t, "
                                   "(SELECT * FROM departments) c "
                                   "WHERE n.id = %1 AND n.id = t.parent_id AND t.id = c.id) ")
                           .arg(organizationId));
    modelDepart->setHideRoot(true);
    modelDepart->select();
}
void InventoryReport::populateWPModel(const QString &filter)
{
    wpModel->setFilter(filter);
    wpModel->select();
}

QList<InventoryReport::departments> InventoryReport::depList(const QModelIndex &parent, QString depName)
{
    QList<departments> dep;
    departments depitem;
    QString curDepName = "";
    for(int i=0;i<modelDepart->rowCount(parent);i++){
        depitem.id = modelDepart->index(i,1,parent).data().toInt();
        curDepName = modelDepart->index(i,0,parent).data().toString();
        depitem.name = depName+curDepName;
        dep.append(depitem);
        if(modelDepart->rowCount(modelDepart->index(i,0,parent))>0){
            dep.append(depList(modelDepart->index(i,0,parent),depName+curDepName+"/"));
        }
    }
    return dep;
}

void InventoryReport::on_createButton_clicked()
{
    bool tableIsCreated = false;
    bool depIsCreated = false;
    QList<departments> dep;
    if(isFirm->isChecked()){
        cInvRep->createTitle(QString("Инвентаризация по фирме: %1").arg(firm->currentText()));
        populateWPModel(QString("CodDepartment = %1").arg(firm->itemData(firm->currentIndex()).toInt()));
        populateModDep(firm->itemData(firm->currentIndex()).toInt());
        dep = depList(modelDepart->index(0,0),"");
    }
    if(isDep->isChecked()){
        cInvRep->createTitle(QString("Инвентаризация по подразделению: %1").arg(depName->text()));
        populateWPModel(QString("CodDepartment = %1").arg(departmentId));
        populateModDep(departmentId);
        dep = depList(modelDepart->index(0,0),"");
    }
    if(isWP->isChecked()){
        cInvRep->createTitle(QString("Инвентаризация по Рабочему мету/Складу: %1").arg(wpName->text()));
        populateWPModel(QString("CodWorkerPlace = %1").arg(workPlaceId));
    }
    if(wpModel->rowCount()>0){
        for(int j = 0; j<wpModel->rowCount();j++){
            orgTexModel->setDevFilter(QString("dev.id IN ( "
                                              "SELECT id FROM device WHERE CodWorkerPlace = %1)")
                                      .arg(wpModel->index(j,0).data().toInt()));
            if(orgTexModel->model()->rowCount()>0){
                if(!tableIsCreated){
                    cInvRep->createTable();
                    tableIsCreated = true;
                }
                for(int n=0; n<orgTexModel->model()->rowCount();n++){
                    cInvRep->addRec(wpModel->index(j,3).data().toString(),orgTexModel->model()->index(n,orgTexModel->model()->cIndex.typeDevName).data().toString(),
                                    orgTexModel->model()->index(n,orgTexModel->model()->cIndex.name).data().toString(),
                                    orgTexModel->model()->index(n,orgTexModel->model()->cIndex.inventoryN).data().toString(),
                                    orgTexModel->model()->index(n,orgTexModel->model()->cIndex.serialN).data().toString());
                    if(!hideComposition->isChecked()){
                        if(orgTexModel->model()->rowCount(orgTexModel->model()->index(n,0))>0)
                            for(int k=0; k<orgTexModel->model()->rowCount(orgTexModel->model()->index(n,0));k++)
                                cInvRep->addSubRec(wpModel->index(j,3).data().toString(),
                                                   orgTexModel->model()->index(k,orgTexModel->model()->cIndex.typeDevName,
                                                                               orgTexModel->model()->index(n,0)).data().toString(),
                                                   orgTexModel->model()->index(k,orgTexModel->model()->cIndex.name,
                                                                               orgTexModel->model()->index(n,0)).data().toString(),
                                                   orgTexModel->model()->index(k,orgTexModel->model()->cIndex.inventoryN,
                                                                               orgTexModel->model()->index(n,0)).data().toString(),
                                                   orgTexModel->model()->index(k,orgTexModel->model()->cIndex.serialN,
                                                                               orgTexModel->model()->index(n,0)).data().toString());
                    }
                }
            }
        }
        tableIsCreated = false;
    }

    if(isFirm->isChecked() || (isDep->isChecked() && givenSubDep->isChecked())){
        for(int i=0;i<dep.count();i++){
            populateWPModel(QString("CodDepartment = %1").arg(dep.at(i).id));
            if(wpModel->rowCount()>0){
                for(int j = 0; j<wpModel->rowCount();j++){
                    orgTexModel->setDevFilter(QString("dev.id IN ( "
                                                      "SELECT id FROM device WHERE CodWorkerPlace = %1)")
                                              .arg(wpModel->index(j,0).data().toInt()));
                    if(orgTexModel->model()->rowCount()>0){
                        if(!depIsCreated){
                            cInvRep->createDepName(dep.at(i).name);
                            depIsCreated = true;
                        }
                        if(!tableIsCreated){
                            cInvRep->createTable();
                            tableIsCreated = true;
                        }
                        for(int n=0; n<orgTexModel->model()->rowCount();n++){
                            cInvRep->addRec(wpModel->index(j,3).data().toString(),orgTexModel->model()->index(n,
                                                                                                              orgTexModel->model()->cIndex.typeDevName)
                                            .data().toString(),
                                            orgTexModel->model()->index(n,orgTexModel->model()->cIndex.name).data().toString(),
                                            orgTexModel->model()->index(n,orgTexModel->model()->cIndex.inventoryN).data().toString(),
                                            orgTexModel->model()->index(n,orgTexModel->model()->cIndex.serialN).data().toString());
                            if(!hideComposition->isChecked()){
                                if(orgTexModel->model()->rowCount(orgTexModel->model()->index(n,0))>0)
                                    for(int k=0; k<orgTexModel->model()->rowCount(orgTexModel->model()->index(n,0));k++)
                                        cInvRep->addSubRec(wpModel->index(j,3).data().toString(),
                                                           orgTexModel->model()->index(k,orgTexModel->model()->cIndex.typeDevName,
                                                                                       orgTexModel->model()->index(n,0)).data().toString(),
                                                           orgTexModel->model()->index(k,orgTexModel->model()->cIndex.name,
                                                                                       orgTexModel->model()->index(n,0)).data().toString(),
                                                           orgTexModel->model()->index(k,orgTexModel->model()->cIndex.inventoryN,
                                                                                       orgTexModel->model()->index(n,0)).data().toString(),
                                                           orgTexModel->model()->index(k,orgTexModel->model()->cIndex.serialN,
                                                                                       orgTexModel->model()->index(n,0)).data().toString());
                            }
                        }
                    }
                }
                tableIsCreated = false;
                depIsCreated = false;
            }
        }
    }
    if(!groupBox_2->isChecked()){
        QPrinter printer(QPrinter::HighResolution);
        QPrintPreviewDialog preview(&printer, this);
        connect(&preview, SIGNAL(paintRequested(QPrinter*)), SLOT(printPreview(QPrinter*)));
        preview.setWindowFlags(Qt::Dialog | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);
        preview.exec();
        cInvRep->clear();
    }else{
        if(fileName->text().isEmpty())
            on_selectFileForSave_clicked();
        if(fileName->text().isEmpty())
            return;
        QString fileN = fileName->text();
        if(!fileN.endsWith(".pdf", Qt::CaseInsensitive)){
            if (! (fileN.endsWith(".odt", Qt::CaseInsensitive) ||
                   fileN.endsWith(".htm", Qt::CaseInsensitive) ||
                   fileN.endsWith(".html", Qt::CaseInsensitive)) )
                     fileN += ".odt";
            cInvRep->write(fileN);
        }else{
            QPrinter *printer = new QPrinter(QPrinter::HighResolution);
            printer->setOrientation(QPrinter::Landscape);
            printer->setOutputFormat(QPrinter::PdfFormat);
            printer->setOutputFileName(fileN);
            cInvRep->print(printer);
            delete printer;
        }
        QMessageBox::information(this, tr("Вывод в файл"),tr("Вывод в файл завершён."),tr("Закрыть"));
        cInvRep->clear();
    }
}
void InventoryReport::printPreview(QPrinter *printer)
{
    cInvRep->print(printer);
}
void InventoryReport::on_isFirm_clicked(bool checked)
{
    if(checked){
        workPlaceId = 0;
        wpName->setText("");
        departmentId = 0;
        depName->setText("");
        createButton->setEnabled(false);
    }
}
void InventoryReport::on_isDep_clicked(bool checked)
{
    if(checked){
        firm->setCurrentIndex(0);
        workPlaceId = 0;
        wpName->setText("");
        createButton->setEnabled(false);
    }
}
void InventoryReport::on_isWP_clicked(bool checked)
{
    if(checked){
        firm->setCurrentIndex(0);
        departmentId = 0;
        depName->setText("");
        createButton->setEnabled(false);
    }
}
void InventoryReport::on_selectFileForSave_clicked()
{
    QString fn = QFileDialog::getSaveFileName(this, tr("Укажите файл"),
                                              QString(), tr("ODF files (*.odt);;HTML-Files (*.htm *.html);;PDF-Files (*.pdf);;All Files (*)"));
    if (fn.isEmpty()) return;
    if (! (fn.endsWith(".odt", Qt::CaseInsensitive) || fn.endsWith(".htm", Qt::CaseInsensitive) || fn.endsWith(".html", Qt::CaseInsensitive) ||
           fn.endsWith(".pdf", Qt::CaseInsensitive)) )
             fn += ".odt";
    fileName->setText(fn);
}

void InventoryReport::on_closeButton_clicked()
{
    emit closeInventoryReportWin();
}

void InventoryReport::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        retranslateUi(this);
        break;
    default:
        break;
    }
}
